﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;
using LevenBlog.Core.Entities;
using LevenBlog.Core.Install;
using LevenBlog.Core.Install.Operations;
using LevenBlog.Core.Utils;

namespace LevenBlog.Web.install {
    public partial class step4 : System.Web.UI.Page {
        protected string Queries;

        protected void Page_Load(object sender, EventArgs e) {
            string type = Request.QueryString["type"];
            string q = Request.QueryString["q"];
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append("webconfig");
            if (!String.IsNullOrEmpty(type) && type == "update") {
                sb.Append("|updatedatabase");
            } else {
                sb.Append("|createdatabase");
                sb.Append("|createtables");
                sb.Append("|createuser");
                sb.Append("|createcategory");
            }
            sb.Append("|routing");
#if DEBUG
#else
            sb.Append("|changedefault");
            sb.Append("|removeinstall");
#endif
            Queries = sb.ToString();
            if (!String.IsNullOrEmpty(q)) {
                string result = String.Empty;
                switch (q) {
                    case "webconfig":
                        result = setupWebConfig();
                        break;
                    case "updatedatabase":
                        result = updateDatabase();
                        break;
                    case "createdatabase":
                        result = setupCreateSqliteDatabase();
                        break;
                    case "createtables":
                        result = setupCreateSqliteTables();
                        break;
                    case "createuser":
                        result = setupUser();
                        break;
                    case "createcategory":
                        result = setupCategories();
                        break;
                    case "routing":
                        result = setupRouting();
                        break;
                    case "removeinstall":
                        result = removeInstall();
                        break;
                    case "changedefault":
                        result = writeDefault();
                        break;
                    default:
                        break;
                }
                if (!String.IsNullOrEmpty(result)) {
                    Response.ContentType = "application/json";
                    Response.Write(result);
                    Response.End();
                }
            }
            if (!IsPostBack) {
                int step = Request.GetSetup();
                if (step < 3)
                    Response.Redirect("step1.aspx");
                (Master as install).SubTitle = "第四步 - 执行安装";
            }
        }

        protected void step4_pre_Click(object sender, EventArgs e) {
            Response.Redirect("step3.aspx");
        }

        private string setupWebConfig() {
            InstallConfig config = InstallConfigService.Read();
            WebConfigItem configItem = new WebConfigItem() {
                AdminPasswordKey = config.AdminPasswordKey,
                ConnectionString = config.ConnectionString,
                PasswordKey = config.PasswordKey,
                PrefixKey = config.PrefixKey,
                ProviderName = config.ProviderName
            };
            WebConfigInstall install = new WebConfigInstall();
            install.Data = configItem;
            OperationResult result;
            using (OperationContext context = new OperationContext()) {
                result = install.Execute(context);
            }
            string message;
            if (result.Result) {
                message = "系统配置成功.";
            } else {
                message = String.Format("系统配置失败\"...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"checkerror\">错误:{0}</span><br />", result.Errors.ToErrorString());
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result.Result, message = message });
        }

        private string setupRouting() {
            InstallConfig config = InstallConfigService.Read();
            string message;
            bool result;
            try {
                InstallExtensions.SaveRoute(config);
                message = "路由配置成功.";
                result = true;
            } catch (Exception ex) {
                message = "路由配置失败..." + ex.Message;
                result = false;
            } 
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result, message = message });
        }

        private string setupUser() {
            InstallConfig config = InstallConfigService.Read();
            LevenBlog.Core.Install.Operations.SqliteUserInstall userInstall = new SqliteUserInstall();
            IList<lb_user> users = new List<lb_user>();
            users.Add(config.DefaultUser);
            userInstall.Data = users;
            OperationResult result;
            using (var context = new OperationContext()) {
                result = userInstall.Execute(context);
            }
            string message;
            if (result.Result) {
                message = "初始化用户成功.";
            } else {
                message = String.Format("初始化用户失败\"...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"checkerror\">错误:{0}</span><br />", result.Errors.ToErrorString());
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result.Result, message = message });
        }

        private string setupCategories() {
            var context = new OperationContext();
            string message;
            bool result;
            try {
                var config = InstallConfigService.Read();
                if (config.DefaultCategories != null) {
                    foreach (var item in config.DefaultCategories) {
                        context.DbFactory.Category.Insert(context.DbProvider, item);
                    }
                }
                message = "初始化导航信息成功.";
                result = true;
            } catch (Exception ex) {
                message = "初始化导航信息失败,错误信息:" + ex.Message;
                result = false;
            } finally {
                context.Dispose();
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result, message = message });
        }

        private string setupCreateSqliteDatabase() {
            OperationContext context = new OperationContext();
            var config = InstallConfigService.Read();
            SqliteDbCreate dbCreate = new SqliteDbCreate();
            dbCreate.Data = config.ConnectionString;
            var result = dbCreate.Execute(context);
            context.Dispose();
            string message;
            if (result.Result) {
                message = "创建Sqlite数据库成功.";
            } else {
                message = String.Format("创建Sqlite数据库失败\"...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"checkerror\">错误:{0}</span><br />", result.Errors.ToErrorString());
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result.Result, message = message });
        }

        private string setupCreateSqliteTables() {
            OperationContext context = new OperationContext();
            var config = InstallConfigService.Read();
            SqliteDatatableInstall install = new SqliteDatatableInstall();
            var result = install.Execute(context);
            context.Dispose();
            string message;
            if (result.Result) {
                message = "初始化数据表成功.";
            } else {
                message = String.Format("初始化数据表失败\"...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"checkerror\">错误:{0}</span><br />", result.Errors.ToErrorString());
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result.Result, message = message });
        }

        private string updateDatabase() {
            string message;
            bool result;
            try {
                var config = InstallConfigService.Read();
                if (config.IsResetSkin) {
                    OperationContext context = new OperationContext();
                    var webConfig = context.DbFactory.Config.Get(context.DbProvider);
                    webConfig.skinname = "default";
                    webConfig.skinauthor = "leven";
                    webConfig.skinpath = "default";
                    webConfig.skinurl = "http://leven.com.cn/";
                    context.DbFactory.Config.Update(context.DbProvider, webConfig);
                    context.Dispose();
                }
                message = "升级数据库设置完成.";
                result = true;
            } catch (Exception ex) {
                result = false;
                message = "升级数据库设置失败,错误信息:" + ex.Message;
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result, message = message });
        }

        private string writeDefault() {
            string path = "~/default.aspx";
            string realPath = Fetch.MapPath(path);
            string message = String.Empty;
            bool result = true;
            if (!File.Exists(realPath)) {
                result = false;
                message = "文件" + path + "未找到";
            } else {
                try {
                    string code = "<%@ Page Language=\"C#\"%>" +
                        Environment.NewLine +
                        "<%Response.Redirect(RouteTable.Routes.GetDefaultPage()); %>";
                    using (StreamWriter sw = new StreamWriter(realPath)) {
                        sw.Write(code);
                    }
                    message = "修改default.aspx成功";
                } catch (Exception ex) {
                    result = false;
                    message = "修改default.aspx失败,错误信息:" + ex.Message;
                }
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result, message = message });
        }

        private string removeInstall() {
            string path = "~/install";
            string realPath = Fetch.MapPath(path);
            string message;
            bool result;
            try {
                removeAll(realPath);
                result = true;
                message = "删除Install目录成功.";
            } catch (Exception ex) {
                result = false;
                message = "删除Install失败,错误信息:" + ex.Message;
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(new { result = result, message = message });
        }

        private void removeAll(string path) {
            if (!Directory.Exists(path)) {
                throw new DirectoryNotFoundException(path);
            }
            DirectoryInfo dir = new DirectoryInfo(path);
            DirectoryInfo[] subdirs = dir.GetDirectories();
            if (subdirs != null) {
                foreach (var item in subdirs) {
                    removeAll(item.FullName);
                }
            }
            FileInfo[] files = dir.GetFiles();
            if (files != null) {
                foreach (var item in files) {
                    File.Delete(item.FullName);
                }
            }
            dir.Delete();
        }
    }
}
